<?php


namespace App\library\services;


use App\Models\WxUser;
use Illuminate\Support\Facades\Redis;

class WxUserService extends BaseServices
{
    /**
     * Author:YangXinPeng
     * 获取用户信息
     * @param $id
     * @return mixed
     */
    public static function getWxUser($id)
    {
        if (empty($id)) {
            return self::fail('参数错误');
        }
        $data = WxUser::find($id);
        $data && $data = $data->toArray();
        return $data;
    }


    /**
     * Author:YangXinPeng
     * 用户签到
     * @param $params
     * @return array
     */
    public static function sign($params)
    {
        Redis::select(config('setting.redis_sign'));
        $uid = $params['uid'];
        $time = $params['searchtime'];
        $originTime = date('Y-m', time()) . "-01 00:00:00";
        $origin = strtotime($originTime);
        $target = strtotime($time);
        //偏移量从0开始
        $offset = floor(($target - $origin) / 86400);
        $newDate = date('Ym', time());
        $key = config('setting.sign') . $uid . ":" . $newDate;
        $isSign = Redis::getBit($key, (int)$offset);
        if ($isSign) {
            return self::fail('当前日期已经完成签到，无需');
        } else {
            Redis::setBit($key, $offset, 1);
        }
    }


    /**
     * Author:YangXinPeng
     * 计算当月的连续签到的天数
     * @param $params
     * @return int
     */
    public static function getContinueSign($params)
    {
        $uid = $params['uid'];
        $newDate = date('Ym', time());
        $key = config('setting.sign') . $uid . ":" . $newDate;
        //计算月份有多少天
        $month = date('m', time());
        $year = date('Y', time());
        $nextMonth = (($month + 1) > 12) ? 1 : ($month + 1);
        $year = ($nextMonth > 12) ? ($year + 1) : $year;
        $days = date('d', mktime(0, 0, 0, $nextMonth, 0, $year));
        //确定区域
        $type = sprintf("u%d", $days);
        $signCount = 0;
        $list = Redis::bitfield($key, 'get', $type, "0");
        if (!empty($list)) {
            $value = $list[0];
            for ($i = 0; $i < $days; $i++) {
                // 是左手边的是高位，右手边的是低位。
                // 取低位连续不为0的个数即为连续签到次数，需考虑当天尚未签到的情况
                if ($value  >> 1 << 1 == $value ) {
                    // 低位为0且非当天说明连续签到中断了
                    if ($i > 0) {
                        break;
                    }
                } else {
                    $signCount += 1;
                }
                $value  >>= 1;
            }
        }
        return $signCount;
    }

    /**
     * Author:YangXinPeng
     * 获取当月签到具体情况
     * @param $uid
     * @return array
     */
    public static function getSignInfo($uid)
    {
        $newDate = date('Ym', time());
        $key = config('setting.sign') . $uid . ":" . $newDate;
        //计算月份有多少天
        $month = date('m', time());
        $year = date('Y', time());
        $nextMonth = (($month + 1) > 12) ? 1 : ($month + 1);
        $year = ($nextMonth > 12) ? ($year + 1) : $year;
        $days = date('d', mktime(0, 0, 0, $nextMonth, 0, $year));
        //确定区域
        $type = sprintf("u%d", $days);
        //获取这个月份所有的签到信息
        //$str = Redis::getBit($key, 0) . decbin(Redis::bitfield($key, 'get', $type, "0")[0]);
        $list = Redis::bitfield($key, 'get', $type, "0");
        $result = [];
        if (!empty($list)){
            $res = $list[0];
            // 由低位到高位，为0表示未签，为1表示已签
            for ($i = $days;$i>0;$i--){
                $date = date('Y-m-d',mktime(0,0,0,$month,$i,$year));
                $result[$date] = $res >> 1 << 1 != $res;
                $res >>= 1;
            }
        }
        return $result;
    }
}
